﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Reflection;
using System.Linq.Expressions;

namespace W.Models.Utils
{
    public static class QueryableExtensions
    {
        public static ObjectQuery<T> IncludeAll<T>(this ObjectQuery<T> sequence, bool deep = false)
        {
            Type type = typeof(T);

            foreach (var attr in GetAttrs(type))
            {
                sequence = sequence.Include(attr.Name);
            }

            return sequence;
        }

        private static IEnumerable<PropertyInfo> GetAttrs(Type t)
        {
            return t.GetProperties().Where(p => !p.PropertyType.Namespace.StartsWith("System"));
        }


        public static ObjectQuery<T> Include<T, TProperty>(this ObjectQuery<T> objectQuery, Expression<Func<T, TProperty>> selector)
        {
            string propertyPath = GetPropertyPath(selector);
            return objectQuery.Include(propertyPath);
        }

        public static string GetPropertyPath<T, TProperty>(Expression<Func<T, TProperty>> selector)
        {
            StringBuilder sb = new StringBuilder();
            MemberExpression memberExpr = selector.Body as MemberExpression;
            while (memberExpr != null)
            {
                string name = memberExpr.Member.Name;
                if (sb.Length > 0)
                    name = name + ".";
                sb.Insert(0, name);
                if (memberExpr.Expression is ParameterExpression)
                    return sb.ToString();
                memberExpr = memberExpr.Expression as MemberExpression;
            }
            throw new ArgumentException("The expression must be a MemberExpression", "selector");
        }

    }

}
